package com.aiwiown.snackmq.network.handler;

import com.aiwiown.snackmq.common.handler.ResponseWriter;
import com.aiwiown.snackmq.common.message.Message;
import io.netty.channel.ChannelHandlerContext;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.nio.ByteBuffer;
import java.util.List;

/**
 * ResponseWriter 接口的 Netty 实现。
 * 它封装了 ChannelHandlerContext，并负责将消息实际写入网络通道。
 * 这个类位于 network 模块，是网络实现细节的一部分。
 */
public class NettyResponseWriter implements ResponseWriter {

    private final ChannelHandlerContext ctx;

    public NettyResponseWriter(ChannelHandlerContext ctx) {
        this.ctx = ctx;
    }

    @Override
    public void writeResponse(Message response) {
        // 将调用委托给 Netty 的具体实现
        ctx.writeAndFlush(response);
    }

    /**
     * 【新增】实现了零拷贝响应的写入方法。
     * 这个方法不会直接将 ByteBuffer 写入通道，而是将它们封装到一个特定的
     * 载体对象 (ZeroCopyResponse) 中，然后将该对象传递给 Netty 的 pipeline。
     * 这样做的好处是，我们可以让专门的编码器 (MessageEncoder) 来处理
     * 这种特殊类型的序列化，保持了代码的整洁和职责的分离。
     *
     * @param messageId 对应原始请求的消息ID。
     * @param buffers   从存储层零拷贝读取的、包含原始消息数据的 ByteBuffer 列表。
     */
    @Override
    public void writeZeroCopyResponse(long messageId, List<ByteBuffer> buffers) {
        // 1. 创建一个专门用于零拷贝响应的载体对象
        ZeroCopyResponse zeroCopyResponse = new ZeroCopyResponse(messageId, buffers);
        // 2. 将这个载体对象写入 Netty pipeline，后续由 MessageEncoder 处理
        ctx.writeAndFlush(zeroCopyResponse);
    }

    /**
     * 一个内部 DTO，用于在 Netty pipeline 中传递零拷贝响应的数据。
     * 这样做可以避免污染通用的 Message 对象，并让编码器可以轻松地识别和处理它。
     */
    @Getter
    @AllArgsConstructor
    public static class ZeroCopyResponse {
        private final long messageId;
        private final List<ByteBuffer> buffers;
    }
}